package com.orgcent.util;

import java.lang.Character.UnicodeBlock;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 各种编码转换：utf8/gbk/unicode之间的转换
 */
public class CharsetHelper {
	public static void main(String[] args) {

		try {
			String s = "中国人";

			System.out.println("gbk2utf8 : " + Arrays.toString(gbk2utf8(s)));

			String fullByte = CharsetHelper.utf8ToUnicode(s);
			System.out.println("utf8ToUnicode : " + fullByte);

			System.out.println(CharsetHelper.unicode2Str(fullByte));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 判断字符串是否全为ASCII字符
	 * @param content
	 * @return false:不是
	 */
	public static boolean isPureAscii(String content){   
		char var;
		for (int i = 0; i < content.length(); i++) {
			var = content.charAt(i);
			if(var < 0 || var > 255) return false;
		}
	    return true;   
	}  
	
	/**
	 * @param chinese
	 * @return
	 */
	public static byte[] gbk2utf8(String chinese) {
		char c[] = chinese.toCharArray();
		byte[] fullByte = new byte[3 * c.length];
		for (int i = 0; i < c.length; i++) {
			int m = (int) c[i];
			String word = Integer.toBinaryString(m);

			StringBuffer sb = new StringBuffer();
			int len = 16 - word.length();
			for (int j = 0; j < len; j++) {
				sb.append("0");
			}
			sb.append(word);
			sb.insert(0, "1110");
			sb.insert(8, "10");
			sb.insert(16, "10");

			String s1 = sb.substring(0, 8);
			String s2 = sb.substring(8, 16);
			String s3 = sb.substring(16);

			byte b0 = Integer.valueOf(s1, 2).byteValue();
			byte b1 = Integer.valueOf(s2, 2).byteValue();
			byte b2 = Integer.valueOf(s3, 2).byteValue();
			byte[] bf = new byte[3];
			bf[0] = b0;
			fullByte[i * 3] = bf[0];
			bf[1] = b1;
			fullByte[i * 3 + 1] = bf[1];
			bf[2] = b2;
			fullByte[i * 3 + 2] = bf[2];

		}
		return fullByte;
	}

	/**
	 * utf-8 转换为unicode
	 * 
	 * @param inStr
	 * @return
	 */
	public static String utf8ToUnicode(String inStr) {
		char[] myBuffer = inStr.toCharArray();

		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < inStr.length(); i++) {
			UnicodeBlock ub = UnicodeBlock.of(myBuffer[i]);
			if (ub == UnicodeBlock.BASIC_LATIN) {
				// 英文及数字等
				sb.append(myBuffer[i]);
			} else if (ub == UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
				// 全角半角字符
				int j = (int) myBuffer[i] - 65248;
				sb.append((char) j);
			} else {
				// 汉字
				short s = (short) myBuffer[i];
				String hexS = Integer.toHexString(s);
				String unicode = "\\u" + hexS;
				sb.append(unicode.toLowerCase());
			}
		}
		return sb.toString();
	}

	/**
	 * unicode 转换utf-8
	 * 
	 * @param theString
	 * @return
	 */
	public static String unicodeToUtf8(String theString) {
		char aChar;
		int len = theString.length();
		StringBuffer outBuffer = new StringBuffer(len);
		for (int x = 0; x < len;) {
			aChar = theString.charAt(x++);
			if (aChar == '\\') {
				aChar = theString.charAt(x++);
				if (aChar == 'u') {
					// Read the xxxx
					int value = 0;
					for (int i = 0; i < 4; i++) {
						aChar = theString.charAt(x++);
						switch (aChar) {
						case '0':
						case '1':
						case '2':
						case '3':
						case '4':
						case '5':
						case '6':
						case '7':
						case '8':
						case '9':
							value = (value << 4) + aChar - '0';
							break;
						case 'a':
						case 'b':
						case 'c':
						case 'd':
						case 'e':
						case 'f':
							value = (value << 4) + 10 + aChar - 'a';
							break;
						case 'A':
						case 'B':
						case 'C':
						case 'D':
						case 'E':
						case 'F':
							value = (value << 4) + 10 + aChar - 'A';
							break;
						default:
							throw new IllegalArgumentException(
									"Malformed   <a><font color=#4563b9>\\uxxxx</font></a>   encoding.");
						}
					}
					outBuffer.append((char) value);
				} else {
					if (aChar == 't')
						aChar = '\t';
					else if (aChar == 'r')
						aChar = '\r';
					else if (aChar == 'n')
						aChar = '\n';
					else if (aChar == 'f')
						aChar = '\f';
					outBuffer.append(aChar);
				}
			} else
				outBuffer.append(aChar);
		}
		return outBuffer.toString();
	}

	/**
	 * 将字符转换为对应的Unicode码
	 * 
	 * 如：'飓' -> '\u98d3'
	 * 
	 * @param str
	 * @return 返回unicode编码
	 */

	public static String str2Unicode(String str) {
		StringBuilder result = new StringBuilder();
		for (int i = 0; i < str.length(); i++) {
			char chr1 = (char) str.charAt(i);
			if (!CharsetHelper.isNeedConvert(chr1)) {
				result.append(chr1);
				continue;
			}
			result.append("\\u").append(Integer.toHexString((int) chr1));
		}
		return result.toString();
	}

	/**
	 * 将Unicode编码转换为中文字符
	 * 
	 * 如：'\u98d3' -> '飓'
	 * 
	 * @param str
	 *            unicode码
	 * @return 中文
	 */

	public static String unicode2Str(String dataStr) {
		StringBuffer result = new StringBuffer();
		Pattern regex = Pattern.compile("\\\\u[0-9a-eA-E]{4}");
		Matcher matcher = regex.matcher(dataStr);
		int index = 0;
		String matchStr;
		while (matcher.find()) {
			matchStr = matcher.group(index); 
			matcher.appendReplacement(result, String.valueOf((char)Integer.parseInt(matchStr.replaceAll("\\\\u", ""), 16)));
		}
		matcher.appendTail(result);
		return result.toString();
	}

	public static boolean isNeedConvert(char para) {
		return ((para & (0x00FF)) != para);
	}

	/**
	 * 将文件名中的汉字转为UTF8编码的串,以便下载时能正确显示另存的文件名.
	 * 
	 * @param s
	 *            原文件名
	 * @return 重新编码后的文件名
	 * @author yue
	 */
	public static String toUtf8String(String s) {
		if (s == null || s.equals("")) {
			return null;
		}
		StringBuffer sb = new StringBuffer();
		try {
			char c;
			for (int i = 0; i < s.length(); i++) {
				c = s.charAt(i);
				if (c >= 0 && c <= 255) {
					sb.append(c);
				} else {
					byte[] b = Character.toString(c).getBytes("utf-8");
					for (int j = 0; j < b.length; j++) {
						int k = b[j];
						if (k < 0)
							k += 256;
						sb.append("%" + Integer.toHexString(k).toUpperCase());
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sb.toString();
	}

	/**
	 * 将10进制的UNICODE内码转换为16进制格式
	 * 
	 * 如：'&#39123;' -> '\u98d3'
	 * 
	 * @param code
	 * @return
	 */
	public static String ucs2ToUnicode(String code) {
		Pattern regex = Pattern.compile("&#\\d{5};");
		Matcher matcher = regex.matcher(code);
		int index = 0;
		String matchStr;
		StringBuffer sb = new StringBuffer();
		while (matcher.find()) {
			matchStr = matcher.group(index);
			matcher.appendReplacement(sb, "\\\\u"
					+ Integer.toHexString(Integer.valueOf(matchStr.replaceAll(
							"[#&;]", ""))));
		}
		matcher.appendTail(sb);
		return sb.toString();
	}
	
	/**
	 * 将10进制的UNICODE内码转换字符
	 * 
	 * 如：'&#39123;' -> '飓'
	 * 
	 * @param code
	 * @return
	 */
	public static String ucs2ToStr(String code) {
		Pattern regex = Pattern.compile("&#\\d{5};");
		Matcher matcher = regex.matcher(code);
		int index = 0;
		String matchStr;
		StringBuffer sb = new StringBuffer();
		while (matcher.find()) {
			matchStr = matcher.group(index);
			matcher.appendReplacement(sb, String.valueOf((char)Integer.parseInt(matchStr.replaceAll(
							"[#&;]", ""))));
		}
		matcher.appendTail(sb);
		return sb.toString();
	}
}
